import Application from 'koa'
import Log from '../sql/module/log'
import { LOGTYPE } from '../lib/enum'
//涉及到密码的修改日志不保存
export default (msg: (arg0: Application.DefaultState) => any, path: any, type: 'update' | 'create' | 'delete') => {
    return async (ctx: Application.DefaultState, next: () => void) => {
        if (type === "update") {
            const from = ctx.from.dataValues || ctx.from
            const dff: any = {}
            const to = ctx.to.dataValues || ctx.to
            const fun = (from: any[], to: any[]) => {
                let changed = false
                const all = [...from, ...to]
                //去重
                const c = [...new Map(all.map(item => [item.id, item])).values()]
                const deff = c.map(item => {
                    const id = item.id
                    const name = item.dataValues.name
                    if (!from.some(it => it.id == id)) {
                        changed = true
                        return {
                            name,
                            id,
                            type: LOGTYPE.add
                        }
                    } else if (!to.some(it => it.id == id)) {
                        changed = true
                        return {
                            name,
                            id,
                            type: LOGTYPE.delete
                        }
                    } else {
                        return {
                            name,
                            id,
                            type: LOGTYPE.default
                        }
                    }
                })
                if (changed) {
                    return deff
                }
            }
            Object.keys(to).forEach(key => {
                if (key === "updatedAt") return
                const f = from[key]
                const t = to[key]
                if (Array.isArray(f)) {
                    const deff = fun(f, t)
                    deff && (dff[key] = deff)
                } else if (t !== f) {
                    dff[key] = f
                }
            })
            if (Object.keys(dff).length) {
                await Log.create({
                    _id: ctx.from.id,
                    name: ctx.auth?.name,
                    path,
                    dff: JSON.stringify(dff),
                    msg: msg(ctx),
                    type,
                    hasReset: 0
                })
            }
        } else {
            await Log.create({
                _id: ctx._id,
                name: ctx.auth?.name,
                path,
                msg: msg(ctx),
                type,
                hasReset: 0
            })
        }
        next()
    }
}